{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "4a0f5c46-e095-4483-ae1e-f7d0d64f193d",
   "metadata": {},
   "source": [
    "# Unitary Function\n",
    "\n",
    "Given a $2^{n}\\times2^{n}$ unitary matrix, the unitary-gate function constructs an\n",
    "equivalent unitary function that acts on $n$ qubits accordingly. For $n>2$, the\n",
    "synthesis process implementation is based on [[1]](#1).\n",
    "\n",
    "\n",
    "Function: `unitary`\n",
    "\n",
    "Arguments:\n",
    "\n",
    "- `elements: CArray[CArray[CReal]]` - A 2d array of complex numbers representing the unitary matrix. \n",
    "- `target: QArray[QBit]` - The quantum state to apply the unitary on. Should be of corresponding size."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "27827d9d-ffc3-4a59-836d-186aa95a0699",
   "metadata": {},
   "source": [
    "## Example\n",
    "\n",
    "This example shows a $2$-qubit unitary function application in the formed $4$-dimensional space."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "e4540517-2287-4ba5-ac2b-2690b8d3653f",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T13:24:36.300427Z",
     "iopub.status.busy": "2024-05-07T13:24:36.299954Z",
     "iopub.status.idle": "2024-05-07T13:24:38.999941Z",
     "shell.execute_reply": "2024-05-07T13:24:38.999153Z"
    }
   },
   "outputs": [],
   "source": [
    "from classiq import Output, QArray, QBit, allocate, create_model, qfunc, unitary\n",
    "\n",
    "UNITARY = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, -1j, 0], [0, 0, 0, 1j]]\n",
    "\n",
    "\n",
    "@qfunc\n",
    "def main(x: Output[QArray[QBit]]):\n",
    "    allocate(2, x)\n",
    "    unitary(UNITARY, x)\n",
    "\n",
    "\n",
    "qmod = create_model(main)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "a45e99e2-0354-404d-a555-83bbb1924f15",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T13:24:39.011972Z",
     "iopub.status.busy": "2024-05-07T13:24:39.010418Z",
     "iopub.status.idle": "2024-05-07T13:24:40.463906Z",
     "shell.execute_reply": "2024-05-07T13:24:40.463289Z"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "from classiq import synthesize, write_qmod\n",
    "\n",
    "write_qmod(qmod, \"unitary\")\n",
    "qprog = synthesize(qmod)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0918567a-9861-4e11-a306-8ed3dfc2216f",
   "metadata": {},
   "source": [
    "## References\n",
    "\n",
    "<a name=\"1\">[1]</a> R. Iten et al, Quantum Circuits for Isometries, Phys. Rev. A 93 (2016). https://link.aps.org/doi/10.1103/PhysRevA.93.032318"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
